<?php
declare(strict_types=1);
namespace App\ZxAdmin\Sys\Curd;
use App\Controller;
use Framework\Libs\Model;
use Framework\Support\Request;
use Swoole\Http\Response;

// hook controller_zxadmin_sys_table_use.php

/**
 * @title   数据结构
 * @auth    true
 * @login   true
 * @menu    true
 * @component vlist/index.vue
 * @icon sc-icon-bug-line
 * @rank  1
 */
class SysTable extends Controller
{
    // hook controller_zxadmin_sys_table_public_start.php

    // hook controller_zxadmin_sys_table_public_end.php
    public function init(string $controller, array $route, string $action, Request $request, Response $response): void
    {
        parent::init($controller, $route, $action, $request, $response); // TODO: Change the autogenerated stub
        if(__LV__!= 'dev'){
            $this->response('0001',[],"本地开发模式才可以操作");
        }
    }


    public const Conf = [
        'pageSize' => 25,
        'pageSizes' => [10, 15, 20, 25, 30, 50, 100, 200, 500],
        'remoteSort' => 0,
        'remoteFilter' => 0,
        'remoteSummary' => 0,
        'hidePagination' => 1,
        'hideRefresh' => 0,
        'hideSetting' => 0,
        'hideDo' => 0,
        'add' => 0,
        'start' => 0,
        'stop' => 0,
        'delete' => 0,
        'import' => 0,
        'export' => 0,
    ];


    /**
     * @title  数据库连接
     * @rank    99
     */
    public function action_Conf_PUT()
    {

        $Columns = [
            [
                'label' => "操作",
                'type' => "button",
                'options' => [
                    ['Name'=>'Curd','Field'=>'Curd','Do'=>'Curd','Type'=>'warning'],
                    //['Name'=>'Edit','Field'=>'Curd','Do'=>'Curd','Type'=>'info'],
                    ['Name'=>'Field','Field'=>'Field','Do'=>'Make'],
                    ['Name'=>'Model','Field'=>'Model','Do'=>'Make'],
                    ['Name'=>'Dao','Field'=>'Dao','Do'=>'Make'],
                ],
                'width' => "50"
            ],
            [
                'label' => "数据表",
                'prop' => "Name",
                'width' => "240"
            ],
            [
                'label' => "Engine",
                'prop' => "Engine",
                'width' => "80"
            ],
            [
                'label' => "编码",
                'prop' => "Collation",
                'width' => "150"
            ],
            [
                'label' => "行数",
                'prop' => "Rows",
                'width' => "60"
            ],
            [
                'label' => "平均长",
                'prop' => "Avg_row_length",
                'width' => "90",
                'sortable' => true,
            ],
            [

                'label' => "空间",
                'prop' => "Data_free",
                'width' => "90",
                'sortable' => true,
            ],
            [

                'label' => "表尺寸",
                'prop' => "Data_length",
                'width' => "90",
                'sortable' => true,
            ],
            [
                'label' => "碎片率",
                'prop' => "Free",
                'width' => "90",
                'sortable' => true,
            ],
            [
                'label' => "索引长",
                'prop' => "Index_length",
                'width' => "90",
                'sortable' => true,
            ],
            [
                'label' => "描述",
                'prop' => "Comment",
                'width' => "400",
            ],
        ];
        // hook controller_zxadmin_sys_table_index_start.php
        $db = _CONF('DB');

        $tabs = [];
        foreach ($db as $k => $v) {
            $tabs[] = [
                'Name' => $v['database_name'],
                'Index' => $k
            ];
        }
        $Tools=[
            //['Name'=>'建表','Field'=>'Table','Do'=>'Table'],
            ['Name'=>'Field','Field'=>'Field','Do'=>'Make'],
            ['Name'=>'Model','Field'=>'Model','Do'=>'Make'],
            ['Name'=>'Dao','Field'=>'Dao','Do'=>'Make'],
            ['Name'=>'RloadPK','Field'=>'RloadPK','Type'=>'danger','Do'=>'RloadPK'],
        ];

        // hook controller_zxadmin_sys_table_index_end.php
        $this->response('0000', ['Tabs' => $tabs, 'Conf' => self::Conf, 'Filter' => [], 'Tools' =>$Tools, 'Columns' => $Columns, 'data' => []]);
    }
    /**
     * @title  数据表
     * @rank    99
     */
    public function action_Index()
    {
        // hook controller_zxadmin_sys_table_index_start.php
        $dblink = $this->request->param('db', 'db');
        empty($dblink) AND $dblink = 'db';
        empty($_ENV['db_class'][$dblink]) && $this->response('0001', [], '数据库不允许访问');
        $model =  new Model();
        $data = $model->show_tables($_ENV['db_class'][$dblink]->conf['database_name'],$_ENV['db_class'][$dblink]);
        /*
        foreach ($_ENV['_models'] as $name => $row) {
            $row->table && $models[$row->table] = $name;
        }
        */
        foreach ($data as $k=>$row) {
            //$data[$k]['IsModel'] = isset($models[$row['Name']]) ? 1 : 0;
            $Name =LowercaseToHump($row['Name']) ;
            if(!empty( $_ENV['sys']['Join'][$Name])){
                $data[$k]['join']=[];
                foreach ($_ENV['sys']['Join'][$Name] as $line){
                    $data[$k]['join'][]=explode('.',$line)[0];
                }
            }
            $data[$k]['Free'] = ($row['Engine']=='MyISAM' && $row['Data_length']) ? bcmul((string)($row['Data_free']/$row['Data_length']),"100",2):"0.00";
            $data[$k]['Data_free'] = humansize($row['Data_free']);
            $data[$k]['Avg_row_length'] = humansize($row['Avg_row_length']);
            $data[$k]['Data_length'] = humansize($row['Data_length']);
            $data[$k]['Index_length'] = humansize($row['Index_length']);
        }

        // hook controller_zxadmin_sys_table_index_end.php
        $this->response('0000', ['data' =>$data]);
    }

    /**
     * @title   字段列表
     * @rank    99
     */
    public function action_Fields()
    {
        // hook controller_zxadmin_sys_table_fields_start.php

        // hook controller_zxadmin_sys_table_fields_end.php
        $this->response('0000', ['data' =>$_ENV['fields']]);
    }



    /**
     * @title  保存数据关联配置
     * @rank   99
     */
    public function action_RloadPK_POST()
    {

        // hook controller_zxadmin_sys_table_save_post_start.php


        $path=__SYSDIR__.'Join.php';
        if(is_file($path)){
           $join = include $path;
        }
        empty($join) && $join=[];
        $pk_arr =[];
        foreach ($_ENV['fields'] as $row){
            if(!empty($row['pk'])){
                $pk_arr[]=['label'=>$row['label'],'pk'=>$row['pk']];
            }
        }
        foreach ($pk_arr as $row){
            foreach ($_ENV['fields'] as $line){
                foreach ($line['id'] as $k){
                    if(strpos($k,$row['pk'])!==false){
                        $line['label'].'.'.$k!=$row['label'].'.'.$row['pk'] && $join[$line['label']][$k]=$row['label'].'.'.$row['pk'];
                    }
                }
            }
        }
        $text = arrayToString($join);
        file_put_contents_try($path, '<?php return '.$text.';?>');

        // hook controller_zxadmin_sys_table_save_post_end.php
        $this->response('0000', ['data' =>$join]);
    }

     /**
     * @title  生成Controller文件
     * @rank   99
     */
    public function action_Ctrl_POST()
    {

        // hook controller_zxadmin_sys_table_save_post_start.php

        $tplname = $this->request->param('tplname', 'Controller');
        $data=[];
        $data['Columns'] = xn_json_encode( $this->request->param('Column', []));
        $data['AddForm'] = xn_json_encode($this->request->param('AddForm', []));
        $data['Tools'] =xn_json_encode( $this->request->param('Tools', []));
        $data['Filter'] = xn_json_encode($this->request->param('Filter', []));
        $data['Conf']['pageSize'] = $this->request->param('pageSize', 0);
        $data['Conf']['remoteSort'] = $this->request->param('remoteSort')?1:0;
        $data['Conf']['remoteFilter'] = $this->request->param('remoteFilter' )?1:0;
        $data['Conf']['remoteSummary'] = $this->request->param('remoteSummary' )?1:0;
        $data['Conf']['hidePagination'] = $this->request->param('hidePagination' )?1:0;
        $data['Conf']['hideRefresh'] = $this->request->param('hideRefresh' )?1:0;
        //$data['Conf']['hideSetting'] = $this->request->param('hideSetting' );
        $data['Conf']['hideDo'] = $this->request->param('hideDo' )?1:0;
        $data['Conf']['add'] = $this->request->param('add' )?1:0;

        $data['Conf']['start'] = $this->request->param('start' )?1:0;
        $data['Conf']['stop'] = $this->request->param('stop')?1:0;
        $data['Conf']['delete'] = $this->request->param('delete')?1:0;
        $data['Conf']['import'] = $this->request->param('import')?1:0;
        $data['Conf']['export'] = $this->request->param('export')?1:0;
        $data['Title'] = $this->request->param('title');
        $data['Auth'] = $this->request->param('auth')?1:0;
        $data['Login'] = $this->request->param('login')?1:0;
        $data['Menu'] = $this->request->param('menu')?1:0;
        $data['Component'] = $this->request->param('component');

        $data['Rank'] = $this->request->param('rank',99);
        $data['Icon'] = $this->request->param('icon');
        $data['Table1'] = $this->request->param('table1');
        $data['Table2'] = $this->request->param('table2');
        $data['Table3'] = $this->request->param('table3');
        $data['Table4'] = $this->request->param('table4');
        $data['Table5'] = $this->request->param('table5');
        $node = $this->request->param('node' );
        empty($node) && $this->response('0001',[],'节点不能为空');
        $nodes = explode('\\',$node,4);
        count($nodes) <2 && $this->response('0001',[],'路径不能为空');
        $data['Node'] = $node;

        $data['Conf']=xn_json_encode($data['Conf']);
        $this->SysCurd->insert($data);


        // hook controller_zxadmin_sys_table_save_post_end.php
        $this->response('0000', ['data' =>[]]);
    }

    /**
     * @title  生成文件
     * @rank   99
     */
    public function action_Make_POST()
    {

        // hook controller_zxadmin_sys_table_make_post_start.php

        $db = $this->request->param('tab', 'db');
        $path = $this->request->param('path', '');
        $replace = $this->request->param('replace', '');
        $filenames = $this->request->param('data', []);
        $filetype = $this->request->param('filetype', 'Field');
        $fileTypes=['Field','Model','Dao'];
        if(!in_array($filetype,$fileTypes,true)){
            $this->response('0001', [], '文件类型错误');
        }
        $filenames = arrlist_values($filenames,'Name');
        $path = match ($filetype) {
            'Field' =>rtrim(__FDADIR__,'/'). trim($path,'/').'/',
            'Model' => __APPDIR__.'Model'.trim($path,'/').'/',
            'Dao' =>  __APPDIR__.'Dao'.trim($path,'/').'/',
        };

        $tpl = file_get_contents(__PLUDIR__.'Curd/Tpl/'.$filetype.'.tpl');
        $model = new Model();
        $model->db=$_ENV['db_class'][$db];
        foreach ($filenames as $k=>$v){
            $tablename=$v;
            $filename = LowercaseToHump(trim($v));

            $tpl_tmp = $tpl;
            $columns = $model->show_columns($tablename);
            $rpi = [];
            $ConstK='';
            $Field=[];
            $ConstComment='';
            $Index='';
            $PkIndex='';
            $ConstArray='';
            $ConstKV='';
            $RowKV='';
            $RowVK='';
            $pk_foreach='';
            $index_foreach='';
            $pk_foreach_kv='';
            $index_foreach_kv='';
            $is_update_at = false;
            $is_create_at = false;
            $is_delete = false;
            $pk='';
            foreach ($columns as $row){

                if($row['Extra'] == 'auto_increment'){
                    $pk = $row['Field'];
                    $PkIndex.='int $'.$row['Field'].',';
                    $pk_foreach.="		\$cond['".$row['Field']."']=$".$row['Field'].";\r\n";
                    $pk_foreach_kv.="isset(\$row['".$row['Field']."'])	&& \$cond['".$row['Field']."']=\$row['".$row['Field']."'];\r\n";
                }
                if($row['Key'] == 'PRI'){
                    $rpi[] = $row['Field'];
                    $index_foreach_kv.="        isset(\$row['".$row['Field']."'])	&& \$cond['".$row['Field']."']=\$row['".$row['Field']."'];\r\n";
                    $index_foreach.="		\$cond['".$row['Field']."']=$".$row['Field'].";\r\n";
                }
                //$row['Null'] == 'NO' && $columns_not_null[] = $row['Field'];
                $ConstKV.="    /*\r\n";
                $Field[]=$row['Field'];

                foreach ($row as $kr => $r) {
                    $ConstKV.='    * @'.$kr.' '.$r."\r\n";
                }
                $ConstKV.="    */\r\n";
                $ConstKV.='    public const '.$row['Field'].' = \''.$row['Field']."';\r\n";

                $type = 'int';
                if(!str_starts_with($row['Type'],'int') && !str_starts_with($row['Type'],'bigint')){
                    $type =$row['Null'] == 'NO'? 'string':'?string';
                    $row['Key'] == 'PRI' &&  $Index.='string $'.$row['Field'].',';
                    $ConstK.='   public  '.$type.' $'.$row['Field'] .($row['Null'] == 'NO'? ";\r\n":  "='';\r\n")  ;
                }else{
                    $row['Key'] == 'PRI' && $Index.='int $'.$row['Field'].',';
                    $ConstK.='   public  '.$type.' $'.$row['Field'].($row['Null'] == 'NO'? ";\r\n":  "=0;\r\n");
                }
                $ConstArray.="    '".$row['Field']."'=>\$this->".$row['Field'].",\r\n";

                $ConstComment.="'".$row['Field']."'=>'".($row["Comment"]??$row['Field'])."',";
                $RowKV.='\''.$row['Field'].'\' => $this->data->'.$row['Field'].",\r\n        ";
                $RowVK.='   isset($data[\''.$row['Field'].'\']) && $this->data->'.$row['Field'].' = ('.ltrim( $type,'?').')$data[\''.$row['Field'].'\'];'."\r\n        ";

                $row['Field']=='CreateAt' && $is_create_at=true;
                $row['Field']=='UpdateAt' && $is_update_at=true;
                $row['Field']=='IsDelete' && $is_delete=true;

            }


            $ConstIndex='';
            $ConstFields='';
            !empty($rpi) &&  $ConstIndex="'". implode("','",$rpi)."'";
            !empty($Field) &&  $ConstFields= "'". implode("','",$Field)."'";
            $ConstComment=rtrim($ConstComment,',');
            $Index=rtrim($Index,',');
            $PkIndex=rtrim($PkIndex,',');
            $RowKV=rtrim($RowKV,',');
            //$reflection = new \ReflectionClass("\\Field\\".$filename.'Columns');
            //$index = constant("\\Field\\".$filename.'Const::index');
            $index_foreach_kv_cond='foreach($cond_array as $row){';
            $index_foreach_kv_cond.="\r\n";
            $i = count($rpi);
            foreach ($rpi as $row){
                //$property = $reflection->getProperty($row);
                //$type = $property->getType()->getName();
               // $index_foreach.="		\$cond['$row']=\$this->request->param('$row',".($type=='int'?0:"").");\r\n";
               // $index_foreach_kv.="isset(\$cond['".$row."'])	&& \$cond['".$row."']=\$row['".$row."'];\r\n";
                //$index_foreach_name[]=$row;
                if($i==1){
                    $index_foreach_kv_cond.="	        \$cond_arr['".$row."'][]=\$row['".$row."'];\r\n";
                }else{
                    $index_foreach_kv_cond.="	        isset(\$row['".$row."']) && \$cond['".$row."']=\$row['".$row."'];\r\n";
                }
            }
            if($i>1) {
                $index_foreach_kv_cond .= "	        !empty(\$cond) && \$cond_arr['OR'][]=\$cond;\r\n";
            }
            /*
            foreach($cond_array as $row){
                $cond=[];
                $index_foreach_kv$
            }
            $cond_arr= isset($cond_arr[1]) ? ['OR'=>$cond_arr]:$cond_arr[0];
            */
            $index_foreach_kv_cond.="       }\r\n";

            // 正则表达式匹配需要替换的部分
            if(empty($rpi)){
                $pattern = "/\/\/need_index_start(.*?)\/\/need_index_end/s";
                $tpl_tmp = preg_replace($pattern, "", $tpl_tmp);
            }

            if(empty($pk)){
                $pattern = "/\/\/need_pk_start(.*?)\/\/need_pk_end/s";
                $tpl_tmp = preg_replace($pattern, "", $tpl_tmp);
            }
            $replace_tmp = [
                '__CLASSNAME__'=>$filename,
                '_tablename_'=>$tablename,
                '$Index$'=>$Index,
                '$PkIndex$'=>$PkIndex,
                '$pk_foreach$'=>trim($pk_foreach),
                '$index_foreach$'=>trim($index_foreach),
                '$pk_foreach_kv$'=>trim($pk_foreach_kv),
                '$index_foreach_kv$'=>trim($index_foreach_kv),
                '$ConstKV$'=>trim($ConstKV),
                '$ConstIndex$'=>trim($ConstIndex),
                '$pk$'=>$pk,
                '$ConstFields$'=>trim($ConstFields),
                '$ConstComment$'=>trim($ConstComment),
                '$ConstK$'=>trim($ConstK),
                '$ConstArray$'=>trim($ConstArray),
                '$RowKV$'=>trim($RowKV),
                '$RowVK$'=>trim($RowVK),
                '$index_foreach_kv_cond$'=>trim($index_foreach_kv_cond),
                "//CreateAt\r\n"=>$is_create_at?'           empty($new[\'CreateAt\']) && $new[\'CreateAt\'] = date("Y-m-d H:i:s");'."\r\n":'',
                "//UpdateAt\r\n"=>$is_update_at?'           empty($new[\'UpdateAt\']) && $new[\'UpdateAt\'] = date("Y-m-d H:i:s");'."\r\n":'',
                "//IsDelete\r\n"=>$is_delete?'          !isset($cond[\'IsDelete\']) && $cond[\'IsDelete\'] = 0;'."\r\n":'',
                '//need_index_start'=>'',
                '//need_index_end'=>'',
                '//need_pk_start'=>'',
                '//need_pk_end'=>'',
                '//need_status_start'=>'',
                '//need_status_end'=>'',
                '//need_option_start'=>'',
                '//need_option_end'=>'',
                '//need_import_start'=>'',
                '//need_import_end'=>'',
                '//need_export_start'=>'',
                '//need_export_end'=>'',
                '//need_field_start'=>'',
                '//need_field_end'=>'',
            ];
            $tpl_tmp = str_replace(array_keys($replace_tmp), array_values($replace_tmp), $tpl_tmp);
            preg_match('/([A-Z][a-z]*)([A-Z][a-z]*)*/', $filename, $matches);
            $p = '';
            if(!empty($matches[1])){
                $p.=$matches[1].'/';
            }

            is_dir($path.$p) OR mkdir($path.$p, 0755, TRUE);
            if(file_exists($path.$p.$filename.$filetype.'.php')){
                file_put_contents_try($path.$p.$filename.$filetype.'.tpl', $tpl_tmp);
            }else{
                file_put_contents_try($path.$p.$filename.$filetype.'.php', $tpl_tmp);
            }
        }

        // hook controller_zxadmin_sys_table_make_post_end.php
        $this->response('0000', ['data' =>[]],'生成结束,重启进程生效');
    }


    // hook controller_sys_api_stat_end.php
}
?>